﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Windows;
using IM.Interfaces;
using IM.Interfaces.Protocols;
using IM.Interfaces.GUI;
using IM.Protocols;
using IM.DataTypes;
using System.Windows.Forms;
using IM.Core.ExtensionNodes;
using System.Threading;

namespace IM.Core
{
	public class Core : ICore
	{
		static IM.Core.Core instance;

		public event ObjectHandler OnContactListShow;

		readonly ProtocolManager protocolManager = new ProtocolManager();
		readonly ManualResetEvent quit = new ManualResetEvent(false);
		Settings settings = null;

		public IProtocolManager ProtocolManager
		{
			get { return protocolManager; }
		}
		public ISettings Settings
		{
			get { return this.settings; }
		}


		private Core()
		{
			this.protocolManager.OnContactListLoad += new ContactListHandler(protocolManager_OnContactListLoad);
			this.protocolManager.OnMessage += new MessageHandler(protocolManager_OnMessage);
			this.protocolManager.OnError += ProtocolManagerOnError;
			this.protocolManager.OnClose += new ObjectHandler(protocolManager_OnClose);
		}

		void protocolManager_OnClose(object sender)
		{
			
		}

		private void SendCore()
		{
			var registeredCommands = Mono.Addins.AddinManager.GetExtensionNodes("/IM/Core/GetCoreAPI", typeof(GetCoreAPINode));

			Logging.Logger.AddImportant("GetCoreAPINode");
			foreach (GetCoreAPINode node in registeredCommands)
			{
				node.SendCore(this);
			}
		}

		void ProtocolManagerOnError (object sender, Exception ex)
		{
			Logging.Logger.AddException(ex);
			//throw ex;
		}

		void protocolManager_OnMessage(object sender, User from, string body)
		{
			if (String.IsNullOrEmpty(body))
				return;

			var registeredCommands = Mono.Addins.AddinManager.GetExtensionNodes("/IM/Core/ChatMessage", typeof(IM.Core.ExtensionNodes.MessageNode));

			foreach (IM.Core.ExtensionNodes.MessageNode node in registeredCommands)
			{
				node.MessageReceived(from, body);
			}
		}

		void protocolManager_OnContactListLoad(object sender, User[] users)
		{
			var registeredCommands = Mono.Addins.AddinManager.GetExtensionNodes("/IM/Core/ContactList/Update", typeof(IM.Core.ExtensionNodes.ContactListUpdateNode));

			Logging.Logger.AddImportant("Contact list update");
			foreach (IM.Core.ExtensionNodes.ContactListUpdateNode node in registeredCommands)
			{
				node.UpdateContactList(users);
			}
		}

		public static Core GetInstance()
		{
			if (instance == null)
				instance = new IM.Core.Core();

			return instance;
		}

		public void LoadSettings(String path)
		{
            if (System.IO.File.Exists(path))
            {
                this.settings = new Settings(path, this.ProtocolManager);

                for (int i = 0; i < this.protocolManager.Count; i++)
                {
                    var protocol = this.ProtocolManager[i].Protocol;
                    var loadedSettings = settings.ProtocolsSettings[protocol.AccountName];
                    this.ProtocolManager[protocol.AccountName].Settings.SetSettingsData(loadedSettings);
                    protocol.LoadSettingsData(loadedSettings);
                }
            }
            else
            {
                this.settings = new Settings(this.ProtocolManager);
            }

            SendCore();
		}

		public void StartGUI()
		{
			if (OnContactListShow != null)
				OnContactListShow(this);

			quit.WaitOne();
		}

		public void Quit()
		{
			this.protocolManager.Close();
			quit.Set();
		}

	}
}
